package moe.codeest.enviews;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

/**
 * Created by codeest on 16/11/6.
 * 最简单的一个，先拿这个热热身~
 */

public class ENRefreshView extends Component implements Component.DrawTask, Component.LayoutRefreshedListener {

    private static final int DEFAULT_LINE_COLOR = 0xffffffff;

    private static final int DEFAULT_LINE_WIDTH = 14;

    private static final int DEFAULT_DURATION = 2000;

    private Paint mPaint;

    private int mWidth, mHeight;

    private int mCircleRadius;

    private float mArrowLength;

    private float mArrowVarLength;

    private float mArcVarLength;

    private int mCenterX, mCenterY;

    private float mArrowX, mArrowY;

    private float mFraction;

    private int mDuration;

    private boolean isInit = false;

    public ENRefreshView(Context context) {
        this(context, null);
    }

    public ENRefreshView(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public ENRefreshView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        int color = AttrUtils.getColorFromAttr(attrSet, "refresh_line_color", DEFAULT_LINE_COLOR);
        int width = AttrUtils.getDimensionFromAttr(attrSet, "refresh_line_width", DEFAULT_LINE_WIDTH);
        mDuration = DEFAULT_DURATION;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE_STYLE);
        mPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        mPaint.setColor(new Color(color));
        mPaint.setStrokeWidth(width);
        addDrawTask(this);
        setLayoutRefreshedListener(this);
    }

    @Override
    public void onRefreshed(Component component) {
        mWidth = component.getWidth();
        mHeight = component.getHeight();
        mCenterX = mWidth / 2;
        mCenterY = mHeight / 2;
        mCircleRadius = mCenterX / 3 * 2;
        mArrowLength = mWidth / 6;
        mArrowX = (float) (-mCircleRadius * Math.sin(30 * Math.PI / 180));
        mArrowY = (float) (-mCircleRadius * Math.cos(30 * Math.PI / 180));
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (!isInit) {
            isInit = true;
            onRefreshed(component);
        }
        if (mFraction <= 0.2) {                     //转上半圈
            mArrowVarLength = (mArrowLength / 0.4f * (0.4f - mFraction));
            mArcVarLength = 119.99f / 0.2f * mFraction;
        } else if (mFraction <= 0.4) {              //转下半圈
            mArrowVarLength = (mArrowLength / 0.4f * (0.4f - mFraction));
            mArcVarLength = 119.99f / 0.2f * (0.4f - mFraction);
        } else if (mFraction <= 0.55) {             //再弹.
            mArrowVarLength = (mArrowLength * 1.4f / 0.15f * (mFraction - 0.4f));
            mArcVarLength = -28 / 0.15f * (mFraction - 0.4f);
        } else if (mFraction <= 0.7) {              //再弹..
            mArrowVarLength = mArrowLength * 1.4f - mArrowLength * 0.7f / 0.15f * (mFraction - 0.55f);
            mArcVarLength = -28 + 36 / 0.15f * (mFraction - 0.55f);
        } else if (mFraction <= 0.85) {             //再弹...
            mArrowVarLength = mArrowLength * 0.7f + mArrowLength * 0.5f / 0.15f * (mFraction - 0.7f);
            mArcVarLength = 14 - 20 / 0.15f * (mFraction - 0.7f);
        } else {                                    //好吧...再弹 =。=
            mArrowVarLength = mArrowLength * 1.2f - mArrowLength * 0.2f / 0.15f * (mFraction - 0.85f);
            mArcVarLength = -6 + 6 / 0.15f * (mFraction - 0.85f);
        }
        canvas.save();
        canvas.translate(mCenterX, mCenterY);
        if (mFraction <= 0.4) {
            canvas.rotate((float) (-10 + 360 / 0.4 * mFraction), 0, 0);
        } else {
            canvas.rotate(-10, 0, 0);
        }
        canvas.drawArc(new RectFloat(-mCircleRadius, -mCircleRadius, mCircleRadius, mCircleRadius), new Arc(0 - mArcVarLength, 240 + mArcVarLength, false), mPaint);
        canvas.drawLine(mArrowX, mArrowY, mArrowX - mArrowVarLength, mArrowY, mPaint);
        canvas.drawLine(mArrowX, mArrowY, mArrowX, mArrowY + mArrowVarLength, mPaint);
        canvas.restore();
    }

    public void startRefresh() {
        mArrowLength = mWidth / 6;
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setDuration(mDuration);
        animatorValue.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                mFraction = v;
                invalidate();
            }
        });
        if (!animatorValue.isRunning()) {
            animatorValue.start();
        }
    }

    public void setDuration(int duration) {
        this.mDuration = duration;
    }
}
